import { CalendarOutlined, FilterOutlined } from '#/utils/antdIcons.js';
import { HttpCode } from '#/utils/contacts';
import { useSetState } from 'ahooks';
import {
  Button,
  Checkbox,
  DatePicker,
  Dropdown,
  Form,
  Input,
  InputNumber,
  message,
  Spin,
  Tooltip,
} from 'antd';
import _ from 'lodash';
import moment from 'moment';
import Empty from '@/tool/components/PageEmpty';
import React, { Fragment, useEffect, useRef } from 'react';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
import VList from 'react-virtualized/dist/commonjs/List';
import { FILTER_TYPE, getInitData } from './helper';
import styles from './index.less';

interface IAppProps {
  title: string;

  onFilterChange: (params: any, operateKey: string) => void;
  colCode: string;
  filterObj: Record<string, unknown>;
  filter: {
    filtersType?: 'filters' | 'date';
    filterOptions?: any[];
    showTime?: boolean | Record<string, unknown>;
    dateRequired?: boolean;
    url?: boolean;
    dicKey?: boolean;
    dateConf?: Record<string, unknown>;
    unitFieldConf?: {
      fieldsList: string[];
      showLabelIndex: number; // 显示字段index
    };
    otherParams?: Record<string, unknown>;
  };
}

const FilterDropdown: React.FunctionComponent<IAppProps> = (props) => {
  const { title = '', onFilterChange, colCode, filterObj = {}, filter = {} } = props;
  const {
    filterOptions,
    filtersType = 'filters',
    showTime = {
      format: 'YYYY-MM-DD HH:mm',
    },
    dateRequired = true,
    url = '',
    dicKey = 'typeList',
    dateConf = {},
    unitFieldConf = {},
    otherParams = {},
  } = filter;
  const [state, setState] = useSetState({
    visible: false,
    loading: false,
    searchValue: '',
    list: [],
    showList: [],
    checkedList: [],
  });

  const ContentMap = {
    [FILTER_TYPE.DATE]: [
      { label: '开始时间', filterType: 'gt', placeholder: '请选择开始时间', key: 'startTime' },
      { label: '结束时间', filterType: 'lt', placeholder: '请选择结束时间', key: 'endTime' },
    ],
    [FILTER_TYPE.RANGE]: [
      { label: '最小值', placeholder: '请输入最小值', key: 'minNumber' },
      { label: '最大值', placeholder: '请输入最大值', key: 'maxNumber' },
    ],
  };

  const formRef = useRef(null);

  const _initData = async () => {
    if (filterOptions?.length) {
      setState({
        list: filterOptions,
        showList: filterOptions,
      });
      return;
    }
    setState({ loading: true });
    const res = await getInitData({ filterType: colCode, url, ...otherParams });
    if (res.statusCode === HttpCode.SUCCESS) {
      if (!_.isEmpty(unitFieldConf)) {
        const list = res?.data?.[dicKey] || [];
        const unitList: any[] = [];
        if (list.length) {
          list.forEach((item) => {
            const objList = [];
            unitFieldConf.fieldsList.forEach((i) => {
              objList.push(item[i]);
            });
            unitList.push(objList.join('@'));
          });
        }
        setState({
          list: unitList || [],
          showList: unitList || [],
          loading: false,
        });
        return;
      }
      setState({
        list: res?.data?.[dicKey] || [],
        showList: res?.data?.[dicKey] || [],
      });
    }
    setState({ loading: false });
  };

  useEffect(() => {
    if (state.visible && !state.list.length) {
      if (filtersType === FILTER_TYPE.FILTERS) {
        _initData();
      }
    }
  }, [state.visible]);

  useEffect(() => {
    const currentValue = filterObj[colCode] || [];
    if (
      (filtersType === FILTER_TYPE.DATE || filtersType === FILTER_TYPE.RANGE) &&
      _.isEmpty(state.checkedList) &&
      _.isEmpty(currentValue)
    ) {
      formRef?.current && formRef?.current?.resetFields();
    }
    if (state.visible && !_.isEmpty(currentValue)) {
      formRef.current &&
        formRef?.current?.setFieldsValue({
          startTime: (currentValue?.[0] && moment(currentValue?.[0])) || null,
          endTime: (currentValue?.[1] && moment(currentValue?.[1])) || null,
          minNumber: currentValue?.[0] || null,
          maxNumber: currentValue?.[1] || null,
        });
    }
    state.visible && setState({ checkedList: currentValue || [] });
  }, [state.visible]);

  const handleSearch = (value) => {
    if (!_.isEmpty(unitFieldConf)) {
      setState({
        showList: state.list.filter((n) => n.indexOf(value ? value.split('@')[1] : value) !== -1),
      });
      return;
    }
    setState({ showList: state.list.filter((n) => n.indexOf(value) !== -1) });
  };

  const onChange = (value) => {
    let resultData = [...state.checkedList];
    if (resultData.indexOf(value) === -1) {
      resultData.push(value);
    } else {
      resultData = resultData.filter((n) => n !== value);
    }
    setState({ checkedList: resultData });
  };

  const onsubmit = async () => {
    if (filtersType === FILTER_TYPE.DATE || filtersType === FILTER_TYPE.RANGE) {
      await formRef?.current?.validateFields();
    }
    if (filtersType === FILTER_TYPE.RANGE) {
      const [minNumber, maxNumber] = state.checkedList;
      if (Number(minNumber) > Number(maxNumber)) {
        message.warning({
          content: '最小值应小于等于最大值',
          style: {
            marginTop: '38vh',
          },
        });
        return;
      }
    }
    setState({ visible: false });
    onFilterChange({ [colCode]: state.checkedList }, 'filter');
  };

  const btnRender = () => {
    return (
      <div className={styles.btnBox}>
        <Button
          onClick={() => {
            formRef?.current &&
              formRef?.current?.setFieldsValue({
                startTime: null,
                endTime: null,
                minNumber: null,
                maxNumber: null,
              });
            setState({ checkedList: [] });
          }}
          className={styles.btn}
        >
          重置
        </Button>
        <Button type="primary" className={styles.btn} onClick={onsubmit}>
          确定
        </Button>
      </div>
    );
  };

  const changeDatePicker = async (value, index) => {
    const data = [...state.checkedList];
    data[index] = moment(value).valueOf();
    setState({ checkedList: data });
    if (data.filter((n) => n).length === 0) {
      await formRef?.current?.validateFields();
    }
  };

  const changeRangeNumber = async (value, index) => {
    const data = [...state.checkedList];
    data[index] = value;
    setState({ checkedList: data });
    if (data.filter((n) => n).length === 0) {
      await formRef?.current?.validateFields();
    }
  };

  const getDisabledDate = (current, index) => {
    const { checkedList } = state;
    if (index === 0) {
      return checkedList[1] && current && current > moment(checkedList[1]);
    }
    return checkedList[0] && current && current < moment(checkedList[0]);
  };

  const overlayNode = () => {
    return (
      <div className={styles.overlayNode}>
        {filtersType === FILTER_TYPE.FILTERS ? (
          <Fragment>
            <div className={styles.search}>
              <Input.Search
                onChange={(e) => setState({ searchValue: e.target.value })}
                value={state.searchValue}
                allowClear
                onSearch={handleSearch}
              />
            </div>
            <Spin spinning={state.loading}>
              <div className={styles.filterContentBox}>
                <div
                  className={styles.filterContent}
                  style={{ height: state.showList.length > 6 ? 270 : 42 * state.showList.length }}
                >
                  {state.showList.length ? (
                    <AutoSizer>
                      {({ width }) => {
                        return (
                          <VList
                            height={state.showList.length > 6 ? 270 : 42 * state.showList.length}
                            rowCount={state.showList.length}
                            rowHeight={42}
                            rowRenderer={({ index, style }) => {
                              const value = state.showList[index];
                              let showContent = state.showList[index];
                              if (!_.isEmpty(unitFieldConf)) {
                                const labelList = showContent && showContent.split('@');
                                showContent = labelList[unitFieldConf?.showLabelIndex] || '';
                              }
                              return (
                                <div
                                  style={style}
                                  key={index}
                                  className={styles.showItem}
                                  onClick={() => onChange(value)}
                                >
                                  <Checkbox
                                    checked={state.checkedList.indexOf(value) !== -1}
                                    value={value}
                                    onChange={() => onChange(value)}
                                    style={{ marginRight: 13 }}
                                  />
                                  <Tooltip
                                    overlayClassName="overtoop"
                                    title={showContent}
                                    placement="topLeft"
                                  >
                                    <div className={styles.showContent}>{showContent}</div>
                                  </Tooltip>
                                </div>
                              );
                            }}
                            width={width}
                          />
                        );
                      }}
                    </AutoSizer>
                  ) : null}
                </div>
                {state.showList.length ? btnRender() : ''}
              </div>
              {!state.showList.length ? (
                <div className={styles.empty}>
                  <Empty />
                </div>
              ) : (
                ''
              )}
            </Spin>
          </Fragment>
        ) : (
          ''
        )}
        {filtersType === FILTER_TYPE.DATE ? (
          <Form ref={formRef} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off">
            {ContentMap[FILTER_TYPE.DATE].map((item, index) => {
              return (
                <Form.Item
                  className={styles.datePicker}
                  key={index}
                  label={item.label}
                  name={item.key}
                  rules={[
                    {
                      required: dateRequired && state.checkedList.filter((n) => n).length,
                      message: '请选择' + item.label,
                    },
                  ]}
                >
                  <DatePicker
                    placeholder={item.placeholder}
                    disabledDate={(current) => getDisabledDate(current, index)}
                    onChange={(value) => changeDatePicker(value, index)}
                    //@ts-ignore
                    showTime={showTime}
                    style={{ minWidth: 155 }}
                    showNow={false}
                    {...dateConf}
                  />
                </Form.Item>
              );
            })}
            {btnRender()}
          </Form>
        ) : (
          ''
        )}
        {filtersType === FILTER_TYPE.RANGE ? (
          <Form ref={formRef} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }} autoComplete="off">
            {ContentMap[FILTER_TYPE.RANGE].map((item, index) => {
              return (
                <Form.Item
                  className={styles.datePicker}
                  key={index}
                  label={item.label}
                  name={item.key}
                  rules={[
                    {
                      required: state.checkedList.filter((n) => n).length > 0,
                      message: '请输入' + item.label,
                    },
                  ]}
                >
                  <InputNumber
                    style={{ width: '100%' }}
                    onChange={(value) => changeRangeNumber(value, index)}
                  />
                </Form.Item>
              );
            })}
            {btnRender()}
          </Form>
        ) : (
          ''
        )}
      </div>
    );
  };

  const _handleVisibleChange = () => {
    setState({ visible: !state.visible });
  };

  const FilterIcon = filtersType === FILTER_TYPE.DATE ? CalendarOutlined : FilterOutlined;

  return (
    <div className={styles.filterDropdown}>
      {title}
      <Dropdown
        trigger={['click']}
        overlay={overlayNode}
        visible={state.visible}
        onVisibleChange={_handleVisibleChange}
      >
        <FilterIcon
          style={{
            fontSize: '9px',
            marginLeft: '11px',
            color: !_.isEmpty(filterObj[colCode]) ? 'var(--font-primary)' : '#9DA0A6',
          }}
        />
      </Dropdown>
    </div>
  );
};

export default FilterDropdown;
